/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package locusts.lib.geom;

import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

/**
 *
 * @author hamish
 */
public class JaggedEllipse implements Shape, Cloneable {

    private final GeneralPath path;

    public JaggedEllipse(double x, double y, double w, double h, int n) {
        path = createJaggedEllipse(x, y, w, h, n);
    }

    public JaggedEllipse(double x, double y, double size, int n) {
        this(x, y, size, size, n);
    }

    protected JaggedEllipse(JaggedEllipse that) {
        this.path = (GeneralPath) that.path.clone();
    }

    private static GeneralPath createJaggedEllipse(double x, double y,
            double w, double h, int n) {
        final GeneralPath p = new GeneralPath();
        p.moveTo((float) (w / 2), 0);
        for (int i = 0; i < n; i++) {
            {
                final double theta = (Math.PI * 2d * i) / n +
                        (Math.random() * Math.PI / n);

                final double d = 0.5;
                final double x0 = x + w * d * Math.cos(theta);
                final double y0 = y + h * d * Math.sin(theta);
                p.lineTo((float) x0, (float) y0);
            }
            {
                final double theta =
                        (Math.PI * 2d * (i + 0.3333)) / n +
                        (Math.random() * Math.PI / n);
                final double d = 0.1 + Math.random() * .4;
                final double x0 = x + w * d * Math.cos(theta);
                final double y0 = y + h * d * Math.sin(theta);
                p.lineTo((float) x0, (float) y0);
            }
            {
                final double theta = (Math.PI * 2d * (i + 0.66666)) /
                        n + (Math.random() * Math.PI / n);
                final double d = 0.5;
                final double x0 = x + w * d * Math.cos(theta);
                final double y0 = y + h * d * Math.sin(theta);
                p.lineTo((float) x0, (float) y0);
            }
        }
        p.closePath();

        return p;
    }

    public Rectangle getBounds() {
        return path.getBounds();
    }

    public Rectangle2D getBounds2D() {
        return path.getBounds2D();
    }

    public boolean contains(double x, double y) {
        return path.contains(x, y);
    }

    public boolean contains(Point2D p) {
        return path.contains(p);
    }

    public boolean intersects(double x, double y, double w, double h) {
        return path.intersects(x, y, w, h);
    }

    public boolean intersects(Rectangle2D r) {
        return path.intersects(r);
    }

    public boolean contains(double x, double y, double w, double h) {
        return path.contains(x, y, w, h);
    }

    public boolean contains(Rectangle2D r) {
        return path.contains(r);
    }

    public PathIterator getPathIterator(AffineTransform at) {
        return path.getPathIterator(at);
    }

    public PathIterator getPathIterator(AffineTransform at, double flatness) {
        return path.getPathIterator(at, flatness);
    }

    @Override
    public JaggedEllipse clone() {
        return new JaggedEllipse(this);
    }
}
